// Classes
TargetArticle targetArticle; 
SourceArticle sourceArticle;

// Articles' Dimensions
int tArticlePosX, tArticlePosY, tArticlePosW, tArticlePosH; // Target article dimensions
int sArticlePosX, sArticlePosY, sArticlePosW, sArticlePosH; // Source article dimensions
int percentPadding;

// Transclusions variables
boolean sourceArticlePressed;   // == true, if a section or sub(subsub...)section is pressed (to use within mousePressed() procedure). ==false otherwise.
boolean transclusionStarted;    // == true, if a source (subsub...)section is dragged. ==false otherwise. 
Section tempTranscludedSection; // Section that was pressed/dragged in the transclusion process.

// Sketch variables 
color mySketchBackground;
int myWidth, myHeight;

void setup() {
  myWidth = (int)(screen.availWidth * 0.6);
  myHeight = (int)(screen.availHeight * 0.8);

  size(myWidth, myHeight);  // Canvas size

  tArticlePosX = (int)(0.05 * myWidth);
  tArticlePosY = (int)(0.05 * myHeight);
  tArticlePosW = (int)(0.4 * myWidth);
  tArticlePosH = (int)(0.9 * myHeight);

  sArticlePosX = (int)(0.55 * myWidth);
  sArticlePosY = (int)(0.05 * myHeight);
  sArticlePosW = (int)(0.4 * myWidth); 
  sArticlePosH = (int)(0.9 * myHeight);

  percentPadding = 4; // Size of padding within the article

  // Init the transclusion variables
  sourceArticlePressed = false;
  transclusionStarted = false;
  tempTranscludedSection = null;

  // Create the article shapes
  sourceArticle = new SourceArticle(sArticlePosX, sArticlePosY, sArticlePosW, sArticlePosH, percentPadding);
  targetArticle = new TargetArticle(tArticlePosX, tArticlePosY, tArticlePosW, tArticlePosH, percentPadding);

  // Cursor of the sketch
  cursor(CROSS);

  // Background
  colorMode(RGB, 255);
  mySketchBackground = color (200, 200, 200);
  colorMode(HSB, 255);

  // Method in the javascript file that loads the files
  loadArticles();
}

void draw() {
  background( mySketchBackground );

  // Draw the documents
  targetArticle.draw();
  sourceArticle.draw();

  // Extra code of the system:
  // This will hide the tooltip if no 'IDLE' section has mouse over in any of the articles
  if ( !targetArticle.hasHighlightedSection() && !sourceArticle.hasHighlightedSection() ) {
    previewText("");
  }

  // If the transclusion had started then draw the hand and the rectangle (not drawn inside section to avoid overlapping)
  if ( transclusionStarted ) { 
    fill(240);

    tempTSW = (int)( tempTranscludedSection.getWidth() / 4 );
    tempTSH = (int)( tempTranscludedSection.getHeight() / 4 );

    rect(mouseX - tempTSW, mouseY - tempTSH, ( tempTSW * 2 ), ( tempTSH * 2 ) );
  }
}

// This method will check if the mouse was pressed on the source article, to be used in mouseDragged() method
void mousePressed() {
  if ( mouseButton == LEFT ) {
    if ( sourceArticle.sectionClicked() ) {
      sourceArticlePressed = true;
    }
    else {
      sourceArticlePressed = false;
    }
  }
}

// Method that checks if a dragging process was made in any source article section.
void mouseDragged() {
  if ( mouseButton == LEFT ) {
    if ( !transclusionStarted ) {
      if ( sourceArticlePressed ) {
        transclusionStarted = true;

        // Get the clicked section and change its status to IN_TRANSCLUSION
        tempTranscludedSection = sourceArticle.getClickedSection();
        tempTranscludedSection.setStatus("IN_TRANSCLUSION");
      }
    }
  }
}

// Method that checks if a source (subsub...)section is released over a section in the target article and registers a new transclusion.
void mouseReleased() {
  if ( transclusionStarted ) {
    // The section is transcluded
    if ( targetArticle.sectionClicked() ) { // If any section (or subsubsub...)section was under the transcluded section 
      targetArticle.addNewTranscludedSection ( targetArticle.getClickedSection() );
    }

    // Resets the transclusion status in the system
    transclusionStarted = false; 
    tempTranscludedSection.setStatus("IDLE"); // Reset the temp section's status

    showTooltip(""); // Really?
  }
}

// Method that checks if any section or (subsubsub...)subsection was clicked.
void mouseClicked() {
  if ( mouseButton == LEFT ) {
    if ( sourceArticle.mouseOver() ) { // The click was inside the document (no matter where)
      sourceArticle.handleClick();
    }

    if ( targetArticle.mouseOver() ) { // The click was inside the document (no matter where)
      targetArticle.handleClick();
    }
  }

  if ( mouseButton == RIGHT ) { 
    if ( targetArticle.sectionClicked() ) {
      targetArticle.changeClickedSectionStatus("DELETE");
    }
  }
  /*
  if ( mouseButton == RIGHT ) {
   sourceArticle.resetSectionsStatus();  // For sections with "IDLE" status
   targetArticle.resetSectionsStatus();
   
   if ( targetArticle.sectionClicked() ) {
   targetArticle.changeClickedSectionStatus("DELETE");
   }
   } 
   */
}

void loadArticleSketch(String tipoArticulo) {
  Article tempArticle; 

  if ( tipoArticulo == "SOURCE") {
    tempArticle = sourceArticle;
    tempSectionsContent = sourceSectionsContent;
    tempSectionsIndex = sourceSectionsIndex;
    tempSectionsParent = sourceSectionsParent;
  }
  else {
    tempArticle = targetArticle;
    tempSectionsContent = targetSectionsContent;
    tempSectionsIndex = targetSectionsIndex;
    tempSectionsParent = targetSectionsParent;
  }

  tempArticle.resetAndDeleteSections();

  int i, j;
  boolean tilEnd = false;

  ArrayList <Section> tempSections = new ArrayList();
  Section newTempSection;

  // Create the sections
  for (i=0; i<tempSectionsContent.length(); i++ ) {
    newTempSection = new Section( tempSectionsContent[i], (int)tempSectionsIndex[i] );

    // Add to the array;
    tempSections.add(newTempSection);
  }

  // Assign parent sections
  for (i=0; i<tempSectionsContent.length(); i++ ) {
    newTempSection = <Section>tempSections.get(i);

    if ( tempSectionsParent[i] == -1 ) { // ROOT Section (NOT Subsection)
      newTempSection.setParentSection(null);
    }
    else {
      newTempSection.setParentSection( <Section>tempSections.get( tempSectionsParent[i] ) );
    }
  }

  // Add subsections to every section
  for (i=0; i<tempSectionsContent.length(); i++ ) {
    newTempSection = <Section>tempSections.get(i);

    for (j=0; j<tempSectionsContent.length(); j++) {
      if ( tempSectionsParent[j] != -1 ) { // If IT'S NOT A ROOT SECTION
        if ( tempSectionsParent[j] == i ) {
          newTempSection.addSubsection( <Section>tempSections.get(j) );
        }
      }
    }
  }

  // Finally, add the "root" sections
  for (i=0; i<tempSectionsContent.length(); i++ ) {
    newTempSection = <Section>tempSections.get(i);

    if ( tempSectionsParent[i] == -1 ) { // ROOT Section (NOT Subsection)
      // Sets the drawing status
      newTempSection.setDrawStatus(true);
      tempArticle.addSection( newTempSection );
    }
  }

  // Color
  tempArticle.setSectionsColor( );
}

/*********************************************************************** ARTICLE ***********************************************************************/
public class Article {
  private ArrayList <Section> articleSections;

  private float articleX;
  private float articleY;
  private float articleW;
  private float articleH;

  private float articlePadding;

  public Article(float newX, float newY, float newW, float newH, int newP) {
    articleSections = new ArrayList<Section>();

    this.articleX = newX;
    this.articleY = newY;
    this.articleW = newW;
    this.articleH = newH;

    this.articlePadding = (float)( (newP * newW)/ 100 );
  }

  public void addNewSection(String newContent, int newIndex) {
    Section newSection = new Section(newContent, newIndex);
    newSection.setStatus("IDLE");
    articleSections.add(newSection);
  }

  public void addSection(Section newSection) {
    newSection.setStatus("IDLE");
    articleSections.add(newSection);
  }

  public void addNewSectionWithIndex(int indexOfNewSection, Section newSection) {
    articleSections.add(indexOfNewSection, newSection);
  }

  public void draw() {
    // Article background
    fill(255);

    // Article shape
    rect(articleX, articleY, articleW, articleH);

    drawSections();
  }

  // Draw method: draws ONLY the 'root' sections
  private void drawSections() {
    Section tempSection;
    float drawingArea = articleH - ((articleSections.size() + 1) * articlePadding);
    float totalSectionsHeight = 0;
    float newPosY = articleY;

    // Total drawing area 
    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);
      totalSectionsHeight = totalSectionsHeight + tempSection.getSectionSize();
    }

    // Draw every section of the article (root sections)
    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);

      // Recursively draw the sections
      drawSection(articleX, newPosY, articleW, (float)(tempSection.getSectionSize() / totalSectionsHeight) * drawingArea, tempSection, articlePadding);

      newPosY  = newPosY + (float)( (tempSection.getSectionSize() * drawingArea) / totalSectionsHeight) + articlePadding;
    }
  }

  // Draw method: draws recursively all the subsections (if shown) of the root sections
  private void drawSection(float aX, float aY, float aW, float aH, Section fromSection, int articlePadding) {
    Section tempSection;
    float drawingArea = aH - (( fromSection.getNumberOfSubsections() + 1 ) * articlePadding);
    float totalSectionsHeight = 0;
    float newPosY = aY + articlePadding;

    if ( fromSection.isDrawn() ) {
      fromSection.draw(aX, aY, aW, aH, articlePadding);    

      // Total drawing area for this
      for (int i=0; i<fromSection.getNumberOfSubsections(); i++) {
        tempSection = fromSection.getSubsection(i);
        totalSectionsHeight = totalSectionsHeight + tempSection.getSectionSize();
      }

      // Draw every section of the article, from this section/subsection
      for (int i=0; i<fromSection.getNumberOfSubsections(); i++) {
        tempSection = fromSection.getSubsection(i);

        drawSection(aX + articlePadding, newPosY, aW - 2*articlePadding, (float)(tempSection.getSectionSize() / totalSectionsHeight) * drawingArea, tempSection, articlePadding);

        newPosY  = newPosY + (float)( (tempSection.getSectionSize() * drawingArea) / totalSectionsHeight) + articlePadding;
      }
    }
  }

  // Method that checks if any of the sections (and subsections) in this document is with the mouse over
  public boolean hasHighlightedSection() {
    Section tempSection;
    boolean varHasHighlightedSection = false;

    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);
      if ( tempSection.mouseOver() || tempSection.subsectionHasMouseOver() ) {
        varHasHighlightedSection = true;
      }
    }

    return varHasHighlightedSection;
  }

  protected Section getSection(int index) {
    Section tempSection;
    tempSection = (Section)articleSections.get(index);
    return tempSection;
  }

  public void setSectionsColor() {
    Section tempSection;
    int colorFactor;

    //colorMode(HSB,255);
    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);

      colorFactor = 50 + (int)( 200 * ( i / articleSections.size() ) );

      if ( tempSection.getNumberOfSubsections() > 0 ) {
        tempSection.setColor( color (colorFactor, 240, 120) );
      }
      else {
        tempSection.setColor( color (colorFactor, 60, 80) );
      }
    }
  }

  public void resetAndDeleteSections() {
    articleSections = new ArrayList<Section>();
  }

  // Method that handles the just-made click (from the mouseClicked event)
  public void handleClick() {
    // Check WHERE was made the click
    // Get clicked section (or subsection) 
    // Check the mouse click from the bottom (lowest) and shown subsection
    Section clickedSection = getClickedSection();

    // if clickedSection == null then  the click was on the document
    if ( clickedSection != null ) {
      clickedSection.setStatus('PREVIEW'); // The status of the section is changed (but internally in the Section class it is re-checked)

      Section tempSection;      
      if ( clickedSection.getParentSection() == null ) {
        for (int i=0; i<articleSections.size(); i++) {
          tempSection=articleSections.get(i);
          if ( tempSection != clickedSection) {
            tempSection.setStatus('IDLE');
          }
        }
      }
    }
    else { // Click was in the document
      resetSectionsStatus(); // Cleans other 'PREVIEW' statuses
    }
  }

  // Method that checks if the mouse is over the RECTANGLE of the document shape
  public boolean mouseOver() {
    boolean isOver = true;

    if (mouseX < articleX) {
      isOver = false;
    }

    if (mouseX > (articleX + articleW)) {
      isOver = false;
    }

    if (mouseY < articleY) {
      isOver = false;
    }

    if (mouseY > (articleY + articleH)) {
      isOver = false;
    }

    return isOver;
  }

  // Method that checks if a section has been clicked
  // NOTE: This method is called when a left click has been detected
  public boolean sectionClicked() {
    Section tempSection;
    boolean hasSectionClicked = false;

    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);

      if ( tempSection.mouseOver() ) {
        hasSectionClicked = true;
      }
      else {
        if ( tempSection.subsectionHasMouseOver() ) {
          hasSectionClicked = true;
        }
      }
    }

    return hasSectionClicked;
  }

  // Method that returns the clicked section (or subsection)
  public Section getClickedSection() {
    Section tempSection, clickedSection, returnSection;

    returnSection = null;
    clickedSection = null;

    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);

      clickedSection = getClickedSubsection ( tempSection );
      if (clickedSection != null) { // There is a subsection
        returnSection = clickedSection;
      }
    }

    return returnSection;
  }

  private Section getClickedSubsection(Section fromSection) {
    Section tempSection, returnSection;
    returnSection = null;

    if ( fromSection.isDrawn() ) {
      // This will check recursively if any subsection has the mouse over
      for (int i=0; i<fromSection.getNumberOfSubsections(); i++) {
        tempSection = fromSection.getSubsection(i);

        returnSection = getClickedSubsection(tempSection);
        if ( returnSection!=null ) {
          i = fromSection.getNumberOfSubsections() + 1;
        }
      }

      if ( returnSection == null ) { // Reached a leaf
        if ( fromSection.mouseOver() ) {
          returnSection = fromSection;
        }
      }
    }

    return returnSection;
  }

  // Method that resets statuses of section, only iff status == 'PREVIEW'
  public void resetSectionsStatus() {
    Section tempSection;

    for (int i=0; i<articleSections.size(); i++) {
      tempSection = this.getSection(i);

      if ( tempSection.getStatus() == "PREVIEW" ) {
        tempSection.setStatus("IDLE");
      }
    }
  }

  // Method that changes a clicked section (or subsection) status to newStatus.
  // NOTE: This is called from main() when a click is made
  // NOTE: If the change is to 'PREVIEW' status, it depends iff the section has subsections
  public void changeClickedSectionStatus(String newStatus) {
    Section tempSection = getClickedSection();

    if ( tempSection.getStatus() != "TRANSCLUDED" ) {
      if ( newStatus != 'DELETE' ) {
        if ( newStatus == 'PREVIEW') {
          if ( tempSection.getNumberOfSubsections() > 0) {
            tempSection.setStatus( newStatus );
          }
        }
        else {
          tempSection.setStatus( newStatus );
        }
      }
      else{
        alert('mierda');
      }
    }
    else {
      // If it is a transcluded section and it is wanted to be deleted
      if ( newStatus == "DELETE" ) {
        tempSection.releaseHighlightParent();
        if ( tempSection.getParentSection() == null ){ // If it is a 'root' transcluded section...
          articleSections.remove( tempSection );
        }
        else{ // If it is subsection
          tempSection.getParentSection().deleteSubsection( tempSection );
        }        
      }
    }
  }
}

/************************************************************************** SOURCE ARTICLE **************************************************************************/
public class SourceArticle extends Article {
  public SourceArticle(float newX, float newY, float newW, float newH, int newP) {
    super(newX, newY, newW, newH, newP);
  }

  public void draw() {
    super.draw();

    // Add new functionalities
  }
}

/************************************************************************** TARGET ARTICLE **************************************************************************/
public class TargetArticle extends Article {
  public TargetArticle(float newX, float newY, float newW, float newH, int newP) { 
    super(newX, newY, newW, newH, newP);
  }

  public void draw() {
    super.draw();
  }

  // Method that adds a new ('TRANSCLUDED') section (tempTranscludedSection) after section whichSection.
  public void addNewTranscludedSection( Section whichSection ) { 
    // tempTranscludedSection is cloned (Content, Color, Status, Transclusion parent section, API index)
    Section newSection = new Section ( tempTranscludedSection.getSectionContent(), color(160), "TRANSCLUDED", tempTranscludedSection, whichSection.getSectionIndex() );

    // It will be added to the respective parent (root or subsection)
    Section whichSectionParent = whichSection.getParentSection();  // The parent is used to look for the index in the target article to add the section in the array

    int indexOfSection;

    // If whichSection is a root section
    if ( whichSectionParent == null ) {
      indexOfSection = this.articleSections.indexOf(whichSection) + 1; // Not before, after.
      super.addNewSectionWithIndex(indexOfSection, newSection);
    }
    else { // It is a subsubsub...section
      indexOfSection = whichSectionParent.getIndexOfSubsection(whichSection) + 1; // Not before, after.
      whichSectionParent.addNewSubsectionWithIndex( indexOfSection, newSection );
    }

    registerNewTranscludedSection( whichSection.getSectionIndex(), tempTranscludedSection.getSectionIndex(), sourceLevels[ tempTranscludedSection.getSectionDepth() ] );
  }
}

/************************************************************************** SECTION **************************************************************************/
public class Section {
  // Section content and color
  private String sectionContent;
  private color sectionColor;

  // Section dimensions
  private float sectionX;
  private float sectionY;
  private float sectionW;
  private float sectionH;

  // Subsections of this section
  private ArrayList <Section> subsections = new ArrayList();
  private Section parentSection = null; // If this is a subsection, != null

    // Status of the Section: IDLE, PREVIEW, IN_TRANSCLUSION, TRANSCLUDED
  private String sectionStatus;

  // Size of section (10 if PREVIEW, else 1)
  private int sizeOfSection;

  // Flag that indicates if the section had 'IDLE' status before 'IN_TRANSCLUSION', used to avoid size-drawing problems.
  private boolean idleBeforeInTransclusion = false;

  // Flag to draw/not_draw this section (used with click events)
  private boolean drawFlag;

  // Transclusion parent data
  private Section transcludedParentSection = null; // Parent of this TRANSCLUDED section
  private boolean forceHighlightFlag = false;

  // Index of the section (MediaWiki API)
  private int sectionIndex;

  // Constructor with content and MediaWiki API index
  public Section(String newSectionContent, int newIndex) {
    this.sectionContent = newSectionContent;
    this.sectionIndex = newIndex;

    this.sizeOfSection = 1;

    this.drawFlag = false;
  }

  // [USED ONLY WHEN CREATING TRANSCLUSIONS] Constructor to use when this section is created from a transclusion
  public Section(String newSectionContent, color newSectionColor, String newSectionStatus, Section newParentSection, int indexOfTarget) {
    this.sectionContent = newSectionContent;
    this.sectionColor = newSectionColor;
    this.sectionStatus = newSectionStatus;
    this.transcludedParentSection = newParentSection; 

    // Transclusion attributes
    this.sectionIndex = indexOfTarget;    
    this.sizeOfSection = 1;
    this.drawFlag = true;
  }

  // Getter and setter of ParentSection
  public void setParentSection(Section pSection) {
    this.parentSection = pSection;
  }

  public Section getParentSection() {
    return this.parentSection;
  }

  // Getter and setter of sectionStatus
  public void setStatus(String newStatus) {
    Section tempSection;    
    if ( this.sectionStatus != 'TRANSCLUDED' ) { // This change of status is only made when the section status is not 'TRANSCLUDED'
      if ( newStatus == 'IDLE' ) {
        for (int i=0; i<subsections.size(); i++) {
          tempSection = subsections.get(i);

          tempSection.setStatus(newStatus); 
          tempSection.setDrawStatus(false);
        }
        this.sectionStatus = newStatus;
      }

      if ( newStatus == 'PREVIEW' ) { // If the section changes to 'PREVIEW', the subsections must be shown
        if (subsections.size() != 0) { // It this subsection has subsections, change the status of them and itself
          for (int i=0; i<subsections.size(); i++) {
            tempSection = subsections.get(i);

            tempSection.setStatus('IDLE');
            tempSection.setDrawStatus(true);
          }

          // Now, all the siblings of this section must be 'IDLE'd
          if ( parentSection!=null ) { // If this isn't a root section
            parentSection.setSiblingsTo('IDLE', this);
          }

          this.sectionStatus = newStatus;
        }
        else {
          this.sectionStatus = 'IDLE'; // No vale la pena que tenga estado preview una sección que no tenga subsecciones.
        }
      }

      if ( newStatus == 'IN_TRANSCLUSION' ) {
        if ( this.sectionStatus == 'IDLE' ) {
          idleBeforeInTransclusion = true;
        }
        else {
          idleBeforeInTransclusion = false;
        }

        this.sectionStatus = newStatus;
      }
    }
    else {
      if ( newStatus == 'DELETE' ) {
      }
    }
  }

  public String getStatus() {
    return this.sectionStatus;
  }

  // Method that sets the status of the siblings of this section, excluding of this operation to sec2exclude
  public void setSiblingsTo(String newStatus, Section sec2exclude) {
    Section tempSection;
    for (int i=0; i<subsections.size(); i++) {
      tempSection = subsections.get(i);

      if ( tempSection != sec2exclude ) {
        tempSection.setStatus(newStatus);
      }
    }
  }

  // Getter of SectionIndex
  public int getSectionIndex() {
    return sectionIndex;
  }

  // Getter and setter of drawFlag
  public boolean isDrawn() {
    return this.drawFlag;
  }

  public void setDrawStatus(boolean newDrawFlag) {
    this.drawFlag = newDrawFlag;
  }

  // Method that adds a new subsection to its subsections
  public void addSubsection(Section newSubsection) {
    this.subsections.add(newSubsection);
    newSubsection.setParentSection( this );
  }

  // [USED ONLY IN TRANSCLUSION] Method that does the same as the article method addNewSectionWithIndex
  public void addNewSubsectionWithIndex(int indexOfNewSection, Section newSection) {
    this.subsections.add(indexOfNewSection, newSection);
    newSection.setParentSection( this );
  }

  // [USED ONLY IN TRANSCLUSION]
  public int getIndexOfSubsection(Section whichSection) {
    return this.subsections.indexOf(whichSection);
  }
  
  // [CALLED FROM targetArticle.setSectionStatus("DELETE")] - IT IS SURE THAT THIS HAS THE SELECTED SUBSECTION
  public void deleteSubsection(Section whichSection){
    //int varSectionIndex = getIndexOfSubsection ( whichSection );
    
    this.subsections.remove( this.subsections.indexOf(whichSection)/*varSectionIndex*/ );
  }

  // Releases the forcing of the parent section
  public void releaseHighlightParent() {
    transcludedParentSection.forceHighlight( false );
  }

  // Method that forces to highlight this section next time in draw method (used when a section was transcluded)
  public void forceHighlight(boolean newForceHighlight) {
    this.forceHighlightFlag = newForceHighlight;
  }

  // Getter methods to section dimensions (used in article class)
  public float getWidth() {
    return this.sectionW;
  }

  public float getHeight() {
    return this.sectionH;
  }

  // Getter of sectionSize
  public int getSectionSize() {
    // Returns: 1 if sectionStatus = 'IDLE', 'TRANSCLUDED', ¿'IN_TRANSCLUSION? 
    // Returns: 50 if sectionStatus = 'PREVIEW' and has at least 1 subsections
    int sizeOfThisSection = 1;

    if ( this.sectionStatus == 'PREVIEW' ) {
      if ( this.subsections.size() > 0 ) { 
        sizeOfThisSection = 50;
      }
    }

    if ( this.sectionStatus == 'IN_TRANSCLUSION' ) { 
      if ( idleBeforeInTransclusion == false) {
        sizeOfThisSection = 50;
      }
    }

    return sizeOfThisSection;
  }

  // Returns: number of subsections of this section
  public int getNumberOfSubsections() {
    return this.subsections.size();
  } 

  // DFaw method: draws the section
  public void draw(float posX, float posY, float objW, float objH, float padding) {
    if ( isDrawn() ) { // If we are allowed to draw this section
      if (sectionStatus == "IDLE") {
        if ( mouseOver() ) { // If has mouse over, then show the tooltip
          fill( color( hue(sectionColor), saturation(sectionColor), brightness(sectionColor) + 60 ) );
          previewText(this.sectionContent);
        }
        else {
          if ( forceHighlightFlag ) {
            fill( color( hue(sectionColor), saturation(sectionColor), brightness(sectionColor) + 80 ) );
          }
          else {
            fill(sectionColor);
          }
        }
      }

      if (sectionStatus == 'PREVIEW') {
        if ( mouseOver() ) { // If has mouse over, then show the tooltip
          fill( color( hue(sectionColor), saturation(sectionColor), brightness(sectionColor) + 60 ) );
          previewText(this.sectionContent);
        }
        else {
          if ( forceHighlightFlag ) {
            fill( color( hue(sectionColor), saturation(sectionColor), brightness(sectionColor) + 80 ) );
          }
          else {
            fill (sectionColor);
          }
        }
      }

      if ( sectionStatus == "IN_TRANSCLUSION" ) {
        fill( color (255, 255, 255) );
      }

      if ( sectionStatus == "TRANSCLUDED" ) {
        if ( mouseOver() ) {
          fill( color( hue(sectionColor), saturation(sectionColor), brightness(sectionColor) + 60 ) );
          this.transcludedParentSection.forceHighlight(true);
          previewText("");
        }
        else {
          fill(sectionColor);
          this.transcludedParentSection.forceHighlight(false);
        }
      }

      // This is done to be able to hightlight the section when the mouse is over
      sectionX = posX + padding;
      sectionY = posY + padding;
      sectionW = objW - 2*padding;
      sectionH = objH; 

      rect(sectionX, sectionY, sectionW, sectionH);
    }
  }

  // Returns: true, if this section has a mouse over (excluding showing subsections)
  // Returns: false, otherwise
  public boolean mouseOver() {
    boolean isOver = true;
    Section tempSection;

    if (mouseX < sectionX) {
      isOver = false;
    }

    if (mouseX > (sectionX + sectionW)) {
      isOver = false;
    }

    if (mouseY < sectionY) {
      isOver = false;
    }

    if (mouseY > (sectionY + sectionH)) {
      isOver = false;
    }

    // If any subsection has mouse over, this section is not with mouse over
    for (int i=0; i<subsections.size(); i++) {
      tempSection = subsections.get(i);
      if ( tempSection.isDrawn() ) {
        if ( tempSection.mouseOver() ) {
          isOver = false;
        }
        else {
          if ( tempSection.subsectionHasMouseOver() ) {
            isOver = false;
          }
        }
      }
    }    

    return isOver;
  }

  // Returns: true, if any sub(sub(sub)...)section has the mouse over
  // Returns: false, otherwise.
  public boolean subsectionHasMouseOver() {
    Section tempSection;
    boolean isOver = false;

    if ( mouseOver() ) {
      isOver = true;
    }
    else {
      // If any subsection has mouse over, this section is not with mouse over
      for (int i=0; i<subsections.size(); i++) {
        tempSection = subsections.get(i);
        if ( tempSection.isDrawn() ) {
          if ( tempSection.subsectionHasMouseOver() ) {
            isOver = true;
          }
        }
      }
    }

    return isOver;
  }

  public void setColor(color newColor) {
    Section tempSection;

    this.sectionColor = newColor;

    // The subsections will be a little bit lighter
    for (int i=0; i<subsections.size(); i++) {
      tempSection = <Section>subsections.get(i);
      tempSection.setColor( color( hue(newColor), saturation(newColor), brightness(newColor) + 20 ) );
    }
  }

  public color getColor() {
    return this.sectionColor;
  }

  public String getSectionContent() {
    return this.sectionContent;
  }

  public boolean getHighlightStatus() {
    return forceHighlightFlag;
  }

  // Method that returns the i-th subsection, or null otherwise
  public Section getSubsection(int i) {
    Section tempSection = null;

    tempSection = <Section> subsections.get(i);

    return tempSection;
  }

  // Method that checks the level 'depth' of this section.
  // Returns: number of 'steps' to reach a root section (parent == null).
  public int getSectionDepth() {
    int sDepth = 0;
    Section tempSection = this;

    while ( tempSection.getParentSection () != null ) {
      sDepth++;
      tempSection = (Section) tempSection.getParentSection();
    }
    return sDepth;
  }
}

